home *** CD-ROM | disk | FTP | other *** search
/ MacWorld Secrets (4th Edition) / Mac Secrets CD 4th Ed.toast / Apple Advanced Technologies / Apple Speech Technologies 1.5 / PlainTalk Developer Info / Speech Recognition Manager SDK / SR Sample Code / Tiny SR Example / CodeWarrior Tiny Example / TinySRApp.c < prev    next >
Text File  |  1996-03-18  |  11KB  |  384 lines

  1. /************************************************************
  2.  
  3. Created: Wednesday, May 4, 1994 at 1:50:15 PM
  4.     TinySRApp.c
  5.     
  6.     Simple Speech Recognition Toolbox Sample Application
  7.  
  8.         Copyright Apple Computer, Inc.    1994
  9.         All rights reserved
  10.  
  11. ************************************************************/
  12.  
  13.  
  14. #include "SpeechRecognition.h"
  15. #include <GestaltEqu.h>
  16. #include <Quickdraw.h>
  17. #include <Dialogs.h>
  18. #include <Fonts.h>
  19. #include <AppleEvents.h>
  20. #include <string.h>
  21. #include <Menus.h>
  22.  
  23. /*****************************************************************************/
  24.  
  25. /* Prototypes and globals */
  26.  
  27. OSErr    InitStuff (void);
  28. OSErr    InitAndStartSpeechRecognition (void);
  29. void    MainLoop (void);
  30. void    CleanupStuff (void);
  31. void    CleanupSpeechRecognitionStuff (void);
  32. OSErr    MakeALanguageModel (SRLanguageModel *lm);
  33. pascal OSErr HandleSpeechDoneAppleEvent (AppleEvent *theAEevt, AppleEvent* reply, long refcon);
  34. void    DisplayString (Str255 str);
  35.  
  36. DialogPtr             gDialog;
  37. SRRecognitionSystem    gSystem;
  38. SRRecognizer            gRecognizer;
  39. SRLanguageModel        gModel;
  40. Boolean                gFinished;
  41.  
  42. #ifndef __MWERKS__
  43. QDGlobals             qd;
  44. #endif
  45.  
  46. /*****************************************************************************/
  47.  
  48. void main ()
  49. {
  50.     OSErr status = InitStuff ();
  51.     if (!status) {
  52.         MainLoop ();
  53.         CleanupStuff ();
  54.     }
  55. }
  56.  
  57. /*****************************************************************************/
  58.  
  59. /* main is the entry point to his program.    */
  60.  
  61. OSErr InitStuff ()
  62. {
  63.     OSErr                status = noErr;
  64.     Rect                rBounds;
  65.     GrafPtr                oldPort;
  66.     SRLanguageObjectFlags                autoFin = kSRNoFinishing;
  67.     MenuHandle            menuH;
  68.     
  69.         /* Adjust heap */
  70.     MaxApplZone();
  71.     MoreMasters();
  72.     MoreMasters();
  73.     
  74.         /* Init toolboxes */
  75.     InitGraf(&qd.thePort);
  76.     InitFonts();
  77.     FlushEvents(everyEvent,0);
  78.     InitWindows();
  79.     InitMenus();
  80.     TEInit();
  81.     InitDialogs(0);
  82.     InitCursor();
  83.  
  84.     menuH = NewMenu (1,"\pSR Test");
  85.     if (menuH) InsertMenu (menuH, 0);
  86.     AddResMenu(menuH,'DRVR');
  87.     DrawMenuBar();
  88.  
  89.  
  90.         /* Make a dialog in which we'll display results */
  91.     SetRect (&rBounds, 50,50,450,150);
  92.     gDialog = NewDialog(NULL,&rBounds,"\p",true,dBoxProc,(WindowPtr)-1,false,0,NULL);
  93.     if (!gDialog)
  94.         status = -1;
  95.     else {
  96.         GetPort (&oldPort);
  97.         SetPort (gDialog);
  98.         MoveTo (10,80);
  99.         TextSize (9);
  100.         DrawString ("\p(Say 'Hi', 'Goodbye', 'What time is it', or 'What day is it'.  Click here to exit.)");
  101.         SetPort (oldPort);
  102.     }
  103.     
  104.     
  105.     if (!status)
  106.         status = InitAndStartSpeechRecognition ();
  107.     
  108.     if (!status)
  109.         gFinished = false;
  110.     else
  111.         gFinished = true;
  112.         
  113.     return status;
  114. }
  115.  
  116. /*****************************************************************************/
  117.  
  118. /* This routine initializes speech recognition, installs an AppleEvent handler
  119.     to handle result notifications from the Speech Recognition Toolbox, calls
  120.     another routine to build a simple language model (which specifies a few
  121.     phrases a user can say), makes that language model active by calling
  122.     SRSetLanguageModel, and starts the recognizer listening.  A more realistic
  123.     application would have more complicated language models (perhaps having
  124.     different language models for different contexts -- using SRSetLanguageModel
  125.     to make the appropriate one active), or would use the language model
  126.     manipulation routines in the Speech Recognition Toolbox to change the
  127.     active language model as the program was used to reflect what the user
  128.     might say in any given situation.
  129. */
  130.  
  131. OSErr InitAndStartSpeechRecognition ()
  132. {
  133.     OSErr    status;
  134.     long    attributes;
  135.     
  136.     /* The SROpenRecognitionSystem loads lots of data and can take a few
  137.         seconds, so display a message indicating this may take a moment.
  138.         This would be a good place to show the watch cursor as well. */
  139.     DisplayString ("\pStarting up...");
  140.  
  141.         /* Make sure SpeechRecognition Toolbox is available */
  142.     status = Gestalt (gestaltSpeechRecognitionVersion, &attributes);
  143.         /* Version number must be at least 1.5 to support Speech Recognition Toolbox API
  144.             documented here. */
  145.     if (!status)
  146.         if (attributes < 0x00000150)
  147.             status = -1;
  148.  
  149.         /* Open a SRRecognitionSystem */
  150.     if (!status)
  151.         status = SROpenRecognitionSystem (&gSystem, kSRDefaultRecognitionSystemID);
  152.  
  153.         /* We don't want the default feedback or listening modes */
  154.     if (false && !status)
  155.         {
  156.         short feedbackModes = kSRNoFeedbackNoListenModes;
  157.         status = SRSetProperty (gSystem, kSRFeedbackAndListeningModes, 
  158.                     &feedbackModes, sizeof (feedbackModes));
  159.         }
  160.         
  161.         /* Create a recognizer with default speech source -- e.g. the desktop microphone */
  162.     if (!status)
  163.         status = SRNewRecognizer (gSystem, &gRecognizer, kSRDefaultSpeechSource);
  164.                 
  165.         /* Install an AppleEvent handler so recognizer can send us recognition results.
  166.             We could alternatively use a callback routine.  That's described elsewhere. */
  167.     if (!status)
  168.         status = AEInstallEventHandler(kAESpeechSuite, kAESpeechDone,
  169.                 NewAEEventHandlerProc (HandleSpeechDoneAppleEvent), 0, false);
  170.             
  171.         /* For this example, we will just make one language model,
  172.             make it active, and start listening. */
  173.  
  174.         /* Make a simple language model (LM) */
  175.     if (!status)
  176.         status = MakeALanguageModel (&gModel);
  177.  
  178.         /* Use this LM in recognition */
  179.     if (!status)
  180.         status = SRSetLanguageModel (gRecognizer, gModel);
  181.  
  182.         /* Release our reference to the LM now, since we don't need it any more.
  183.             The recognizer keeps it's own reference to the LM until we release the 
  184.             recognizer. */
  185.     if (!status)
  186.         status = SRReleaseObject (gModel);
  187.  
  188.  
  189.         /* Have the recognizer start processing sound */
  190.     if (!status)
  191.         status = SRStartListening (gRecognizer);
  192.  
  193.     if (!status)
  194.         DisplayString ("\pReady");
  195.     else
  196.         DisplayString ("\pBummer");
  197.  
  198.     return status;
  199. }
  200.  
  201.  
  202. /*****************************************************************************/
  203.  
  204. void MainLoop ()
  205. {
  206.     Boolean         gotEvent;
  207.     EventRecord        event;
  208.     DialogPtr        theDialog;
  209.     short            itemHit;
  210.     Point            pt;
  211.     GrafPtr            oldPort;
  212.     
  213.         /* Here's our overly-simple main event loop */
  214.         /*    We quit if mouse is clicked in window,    */
  215.         /*    or if any key is clicked.                */
  216.         /*    We also dispatch AppleEvents.            */
  217.     while (!gFinished) {
  218.         gotEvent = WaitNextEvent(everyEvent, &event, 0xFFFFFFFF, NULL);
  219.         if (IsDialogEvent(&event))
  220.             DialogSelect(&event, &theDialog, &itemHit);
  221.         if (gotEvent) 
  222.             switch (event.what) {
  223.                 case mouseDown :
  224.                     pt = event.where;
  225.                     GetPort (&oldPort);
  226.                     SetPort (gDialog);
  227.                     GlobalToLocal (&pt);
  228.                     if (PtInRect (pt, &((GrafPtr)gDialog)->portRect))
  229.                         gFinished = true;
  230.                     SetPort (oldPort);
  231.                     break;
  232.                 case keyDown :
  233.                     gFinished = true;
  234.                     break;
  235.                 case kHighLevelEvent :
  236.                     AEProcessAppleEvent(&event);
  237.                     break;
  238.                 default :
  239.                     break;
  240.             }
  241.     }
  242. }
  243.  
  244. /*****************************************************************************/
  245.         
  246. void CleanupStuff ()
  247. {
  248.     CleanupSpeechRecognitionStuff ();
  249.     
  250.     if (gDialog)
  251.         DisposeDialog (gDialog);
  252. }
  253.  
  254. /*****************************************************************************/
  255.  
  256. void CleanupSpeechRecognitionStuff ()
  257. {
  258.     OSErr status;
  259.     status = SRStopListening (gRecognizer);    /* stop processing incoming sound */
  260.     status = SRReleaseObject (gRecognizer);    /* balance SRNewRecognizer call */
  261.     status = SRCloseRecognitionSystem (gSystem);    /* balance SROpenRecognitionSystem call */
  262. }
  263.  
  264. /*****************************************************************************/
  265.  
  266. /* Here we build a language model to tell the recognizer what it should listen
  267.     for.  Of course, these strings should never be hard-coded into any app, but
  268.     we're doing it here so that under Think you don't need to provide any
  269.     resources.
  270. */
  271.  
  272. OSErr MakeALanguageModel (SRLanguageModel *model)
  273. {
  274.     OSErr            status;
  275.     SRLanguageModel    newModel;
  276.     const char        *lmName = "<Sample LM>";
  277.     const char        *phraseStrings[] = {
  278.                         "Hi",
  279.                         "Goodbye",
  280.                         "What time is it",
  281.                         "What day is it",
  282.                         0
  283.                     };
  284.     const char        **phraseStr = phraseStrings;
  285.     
  286.     
  287.         /*    make a simple language model (LM) */
  288.     status = SRNewLanguageModel (gSystem, &newModel, lmName, strlen (lmName));
  289.         
  290.         /*    add each phrase to LM */
  291.     if (!status) {
  292.         while (!status && *phraseStr) {
  293.             status = SRAddText (newModel, *phraseStr, strlen (*phraseStr), 0);
  294.             phraseStr++;
  295.         }
  296.             
  297.             /*    release newly created LM if an error occured while adding phrases */
  298.         if (status)
  299.             SRReleaseObject (newModel);
  300.     }
  301.     
  302.         /*    return new LM */
  303.     if (!status)
  304.         *model = newModel;
  305.  
  306.     return status;
  307. }
  308.  
  309. /*****************************************************************************/
  310.  
  311. /* Here's an AppleEvent handler for handling the kAESpeechDone event of the
  312.     kAESpeechSuite -- i.e. the event indicating a recognition attempt was made.
  313.     The keySRSpeechStatus parameter gives the status of the recognition.  If it
  314.     is noErr, then the keySRSpeechResult parameter gives a SRRecognitionResult with the
  315.     various representations of the words the user spoke.
  316. */
  317.  
  318. pascal OSErr HandleSpeechDoneAppleEvent (AppleEvent *theAEevt, AppleEvent* reply, long refcon)
  319. {
  320.     long                actualSize;
  321.     DescType            actualType;
  322.     OSErr                status = 0, recStatus = 0;
  323.     SRRecognitionResult    recResult;
  324.     Str255                str;
  325.     Size                len;
  326.     
  327.         /* Get status */
  328.     status = AEGetParamPtr(theAEevt,keySRSpeechStatus,typeShortInteger,
  329.                     &actualType, (Ptr)&recStatus, sizeof(status), &actualSize);
  330.  
  331.         /* Get result */
  332.     if (!status && !recStatus)
  333.         status = AEGetParamPtr(theAEevt,keySRSpeechResult,
  334.                     typeSRSpeechResult, &actualType, (Ptr)&recResult,
  335.                     sizeof(SRRecognitionResult), &actualSize);
  336.                     
  337.         /* Get text of words in result.
  338.             Could also get actual phrase, path, or LM objects using other
  339.             format property selectors. If we did that, we'd also want to
  340.             release those objects when we were done using them here.*/
  341.     if (!status) {
  342.         len = 255;
  343.         status = SRGetProperty (recResult, kSRTEXTFormat, str+1, &len);
  344.         if (!status) {
  345.             str[0] = len;
  346.                 
  347.                 // Release SRRecognitionResult since we are done with it!!! 
  348.                 //    The toolbox has given us a reference to this object, and
  349.                 //    assumes we are still using it until we call SRReleaseObject
  350.                 //    with it.
  351.             SRReleaseObject (recResult);
  352.         }
  353.     }
  354.     
  355.     if (!status)
  356.         DisplayString (str);
  357.     else
  358.         DisplayString ("\pRecognition error");
  359.  
  360.     return status;
  361. }
  362.  
  363. /*****************************************************************************/
  364.  
  365. void DisplayString (Str255 str)
  366. {
  367.     GrafPtr    oldPort;
  368.     Rect    theRect;
  369.     
  370.     GetPort (&oldPort);
  371.     SetPort (gDialog);
  372.     theRect = ((GrafPtr)gDialog)->portRect;
  373.     theRect.bottom = theRect.bottom-30;
  374.     EraseRect(&theRect);
  375.     TextSize (12);
  376.     MoveTo (40,30);
  377.     DrawString (str);
  378.     SetPort (oldPort);
  379. }
  380.  
  381. /*****************************************************************************/
  382.  
  383.  
  384.